home *** CD-ROM | disk | FTP | other *** search
- {Binary file Interprocess Communications unit}
- {BINIPC V1.01 Copyright 1989 Michael Day as of 16 April 1989}
- {all rights reserved}
-
- {The IPC allows you to communicate with the calling program.}
- {this is accomplished through a section of memory which is allocated}
- {below the BIN program's PSP segment to contain the register information}
- {that was passed to the BIN program, and to allow the BIN program to}
- {pass it's own register values back to the caller.}
- {Access to several additional support variables is also provided}
- {most notably, the Entry address into the BIN program which allows}
- {it to be changed for subsequent re-entry into the program.}
- {(You must declare any alternate entry as FAR)}
-
- unit BinIpc;
- interface
-
- type BinEntry = pointer; {entry address of BIN file}
- PrcType = procedure; {procedure pointer type}
-
- {Inter Process Communication format}
- IPCrecType = record
- {BIPC contains 'BIPC' if the program has been properly loaded.}
- BIPC : array[0..3] of char; {validty check variable}
-
- {The following variables contain the caller's register values}
- {these can be used to pass information between the caller and}
- {the loaded BIN program. These registers are then returned to}
- {the caller upon exit. Be careful about changing the registers}
- {since most programs expect certain registers to remain intact.}
- {Dbase expects DS,SS,SP to remain unchanged. Others also expect}
- {BP to remain unchanged. Some expect all of them to remain intact.}
- OldFlgs : word; {flags on entry to the BIN file}
- OldAX : word; {AX register on entry to the BIN file}
- OldBX : word; {BX register on entry to the BIN file}
- OldCX : word; {CX register on entry to the BIN file}
- OldDX : word; {DX register on entry to the BIN file}
- OldSI : word; {SI register on entry to the BIN file}
- OldDI : word; {DI register on entry to the BIN file}
- OldDS : word; {DS register on entry to the BIN file}
- OldES : word; {ES register on entry to the BIN file}
- OldBP : word; {BP register on entry to the BIN file}
- OldStk : pointer; {SS:SP registers, stack on entry to the BIN file}
-
- {You can change work pointer to cause the next entry into the BIN}
- {program to occur at a different address. This will cause a warm}
- {entry which means that the PSP will not be rebuilt, and the last}
- {internal stack address is used. If WrkPtr = LoadPtr, then the PSP}
- {is completely rebuilt, and the stack is set to the original entry}
- {location found in the EXE header. If you wish the BIN program to}
- {use the caller's stack, set WrkStk to nil (0). Setting it to}
- {LoadStk will return it to the BIN program's stack area.}
- WrkPtr : BinEntry; {CS:IP, pointer to current Entry address of BIN}
- WrkStk : pointer; {stack on exit from BIN file}
-
- {The following varibles are provided for reference only,}
- {they are not to be changed, or odd things may happen.}
- BinDS : word; {DS seg on exit from BIN file}
- BinSS : word; {SS seg on exit from BIN file}
- LoadPtr : pointer; {original entry point of BIN file}
- LoadStk : pointer; {original stack location of BIN file}
- PspSeg : word; {current PSP seg of BIN file}
- OldPsp : word; {caller's PSP segment}
- PrgSiz : word; {Total size of bin file in paragraphs}
- end;
-
- {Once the BIN program is running, IPC will point to the IPC structure}
- var IPC : ^IPCrecType; {IPC points to the IPC record}
-
- {----------------------------------------------------------------------}
-
- function GetDbString(var S:string):boolean;
- function SetDbString(var S:string):boolean;
- procedure BinLoadCheck;
- procedure SetBinEntry(Prc:PrcType);
-
-
- { ******************************************************************** }
- implementation
-
- {-----------------------------------------------------------------------}
- {Read the Dbase string that was passed. If no string passed, returns}
- {false and a null string. If string passed, returns true and the string.}
- function GetDbString(var S:string):boolean;
- type DbsType = array[0..255] of char;
- var DbsPtr : ^DbsType;
- i : integer;
- begin
- GetDbString := false;
- S := '';
- if IPC = nil then Exit;
- DbsPtr := pointer((longint(IPC^.OldDS) shl 16) + IPC^.OldBX);
- if DbsPtr = nil then Exit; {if ptr = 0 then no var passed}
- i := 0;
- while DbsPtr^[i] <> #0 do
- begin
- S[succ(i)] := DbsPtr^[i];
- inc(i);
- end;
- S[0] := char(i);
- GetDbString := true;
- end;
-
- {---------------------------------------------------------------------}
- {Write to a Dbase string that was passed. If no string passed, returns}
- {false and no change is attempted. If a string was passed, returns true}
- {and the string is changed. (Note: the string lengths *must* match, or}
- {Dbase will get upset. This function will return false if no string was}
- {passed, Otherwise it returns true. It will only copy a string upto the}
- {length of the string, or the size of the Dbase string. If the Dbase}
- {string length was zero, then nothing is copied, but no error is given.}
- function SetDbString(var S:string):boolean;
- type DbsType = array[0..255] of char;
- var DbsPtr : ^DbsType;
- i : integer;
- begin
- SetDbString := false;
- if IPC = nil then Exit;
- DbsPtr := pointer((longint(IPC^.OldDS) shl 16) + IPC^.OldBX);
- if DbsPtr = nil then Exit; {if DS:BX is nil, then no pointer was passed}
- i := 0;
- while (DbsPtr^[i] <> #0) and (i <= length(S)) do
- begin
- DbsPtr^[i] := S[succ(i)];
- inc(i);
- end;
- SetDbString := true;
- end;
-
- procedure SetBinEntry(Prc:PrcType);
- begin
- PrcType(IPC^.WrkPtr) := Prc;
- end;
-
- {----------------------------------------------------------------------}
- {check for load error, if bad, output an error message and stop program}
- procedure TtyChar(Ch:char; Color:byte);
- inline($55/$B4/$0F/$CD/$10/$5D/$58/$88/$C3/$58/$55/$B4/$0E/$CD/$10/$5D);
- {push bp, mov ah,$f, int $10, pop bp, pop ax, mov bl,al, pop ax,}
- {push bp, mov ah,$e, int $10, pop bp}
- procedure BinLoadCheck;
- var i : integer;
- S : string[80];
- begin
- if IPC <> nil then Exit;
- S := #10+#13+'** Error: BIN IPC damaged - Program aborted **'+#10+#13;
- for i := 1 to length(S) do
- TtyChar(S[i],15);
- Halt;
- end;
-
- { ********************************************************* }
- {initialize IPC pointer, and check if valid}
- begin
- IPC := pointer(pointer((longint(PrefixSeg)-2) shl 16)^);
- if (IPC^.BIPC <> 'BIPC') then IPC := nil; {nil = invalid interface record}
- end.